home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Tool Chest / Testing & Debugging / General tools / Audit app & dcmd / Src / AuditDocument.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-17  |  13.3 KB  |  578 lines  |  [TEXT/KAHL]

  1. /*                                    AuditDocument.c                                */
  2. /*
  3.  * DisplayAudit.c
  4.  * Copyright © 1992-93, Apple Computer Inc. All Rights Reserved.
  5.  * Programmed by Martin Minow,
  6.  *    Internet:    minow@apple.com
  7.  *    AppleLink:    MINOW
  8.  */
  9. #include "DisplayAudit.h"
  10.  
  11. #ifndef TESTING
  12. #define TESTING                    0
  13. #endif
  14. #if TESTING
  15. void            TestAuditStatusLocationUsingAnExtremelyLongFunctionName(void);
  16. pascal void        TestPascalVoidFunction(void);
  17. pascal short    TestPascalShortFunction(void);
  18. pascal OSErr    TestPascalFunctionWithParameters(Ptr, Ptr);
  19. #endif
  20.  
  21. static void
  22. GetTagViewRect(
  23.         register DocumentPtr            documentPtr,
  24.         Rect                            *viewRect
  25.     )
  26. {
  27.         *viewRect = (**DOC.tagButton).contrlRect;
  28.         viewRect->left = viewRect->right;
  29.         viewRect->right = WINDOW.portRect.right - kScrollBarWidth;
  30.         InsetRect(viewRect, 4, 0);
  31. }
  32.  
  33. /*
  34.  * MakeDocumentWindow creates a window that will hold the log information.
  35.  * It then creates/initializes the Audit Record for that window. The strings
  36.  * should be fetched from the resource fork.
  37.  */
  38. void
  39. MakeDocumentWindow(void)
  40. {
  41.         OSErr                            status;
  42.         register DocumentPtr            documentPtr;
  43.         WindowPtr                        theWindow;
  44.         short                            windowWidth;
  45.         short                            windowHeight;
  46.         Point                            windowTopLeft;
  47.         Rect                            viewRect;
  48.         SFReply                            sfReply;
  49.         Str255                            windowTitle;
  50.         short                            listFontNumber;
  51.         StringPtr                        message;
  52.         Boolean                            saveAuditEnable;
  53.         FontInfo                        info;
  54.         short                            lineHeight;
  55.         
  56.         documentPtr = (DocumentPtr) NewPtrClear(sizeof (DocumentRecord));
  57.         FailNIL(documentPtr, kErrNoMemory);
  58.         TRY {
  59.             AuditFileDialog(
  60.                 DLOG_SFPutFile,
  61.                 "\pAudit Log File",
  62.                 "\pAudit Log",
  63.                 &sfReply        
  64.             );
  65.             gParameterUpdateNeeded = TRUE;
  66.             DOC.auditIdent = PARM.auditIdent;
  67.             DOC.enableAudit = PARM.enableAudit;
  68.             DOC.scanCount = PARM.auditRecords;
  69.             if (gHasColorQuickDraw) {
  70.                 theWindow = GetNewCWindow(
  71.                                 WIND_Document,
  72.                                 &DOC.windowRecord,
  73.                                 (WindowPtr) -1
  74.                             );
  75.             }
  76.             else {
  77.                 theWindow = GetNewWindow(
  78.                                 WIND_Document,
  79.                                 &DOC.windowRecord,
  80.                                 (WindowPtr) -1
  81.                             );
  82.             }
  83.             FailNIL(theWindow, kErrCreateTextWindow);
  84.             if ((long) theWindow != (long) documentPtr)        /* Can't happen        */
  85.                 FailNIL(NULL, kErrCreateTextWindow);        /* It did!            */
  86.             SetPort(WINDOW_PTR);                            /* Do this first    */
  87.             GetWTitle(WINDOW_PTR, windowTitle);
  88.             BlockMove(
  89.                 &DOC.auditIdent,
  90.                 &windowTitle[windowTitle[0] + 1 - sizeof (OSType)],
  91.                 sizeof (OSType)
  92.             );
  93.             SetWTitle(WINDOW_PTR, windowTitle);
  94.             windowWidth = width(qd.screenBits.bounds) / 2;
  95.             if (windowWidth < kMinWindowWidth)
  96.                 windowWidth = kMinWindowWidth;
  97.             windowHeight = height(qd.screenBits.bounds) - (GetMBarHeight() * 2) - 4;
  98.             if (windowHeight < kMinWindowHeight)
  99.                 windowHeight = kMinWindowHeight;
  100.             windowTopLeft.h = qd.screenBits.bounds.left + 2;
  101.             windowTopLeft.v = qd.screenBits.bounds.top + GetMBarHeight() * 2 + 2;
  102.             TextFont(applFont);
  103.             TextSize(kApplFontSize);
  104.             TextFace(normal);
  105.             DOC.tagButton = GetNewControl(CNTL_TagButton, WINDOW_PTR);
  106.             FailNIL(DOC.tagButton, kErrCreateTextWindow);
  107.             DOC.tagLine = (**DOC.tagButton).contrlRect.bottom + 6;
  108.             GetTagViewRect(documentPtr, &viewRect);
  109.             GetFNum(PARM.fontName, &listFontNumber);
  110.             TextFont(listFontNumber);
  111.             TextSize(PARM.fontSize);
  112.             GetFontInfo(&info);
  113.             /*
  114.              * Shrink the window height so an integral number of lines are shown.
  115.              */
  116.             lineHeight = info.ascent + info.descent + info.leading;
  117.             windowHeight -= (DOC.tagLine + kScrollBarOffset);
  118.             windowHeight -= (windowHeight % lineHeight);
  119.             windowHeight += (DOC.tagLine + kScrollBarOffset);
  120.             MoveWindow(WINDOW_PTR, windowTopLeft.h, windowTopLeft.v, FALSE);
  121.             SizeWindow(WINDOW_PTR, windowWidth, windowHeight, FALSE);
  122.             BringToFront(WINDOW_PTR);
  123.             ShowWindow(WINDOW_PTR);
  124.             SelectWindow(WINDOW_PTR);
  125.             /*
  126.              * Add the tag button and tag text handle for time-stamping.
  127.              */
  128.             DOC.tagEditHandle = CreateEditHandle(
  129.                         &viewRect,
  130.                         applFont,
  131.                         kApplFontSize,
  132.                         MENU_Edit,
  133.                         STRN_EditMenu,
  134.                         0                    /* No RefCon        */
  135.                     );
  136.             FailNIL(DOC.tagEditHandle, kErrCreateTextWindow);
  137.             TESetText((Ptr) "•", 1, GetTEHandle(DOC.tagEditHandle));
  138.             /*
  139.              * Build a display log in the window.
  140.              * To do: let the user choose the font and size.
  141.              */
  142.             viewRect = WINDOW.portRect;
  143.             viewRect.top = DOC.tagLine;
  144.             viewRect.right -= kScrollBarOffset;
  145.             viewRect.bottom -= kScrollBarOffset;
  146.             DOC.logListHandle = CreateLog(
  147.                     &viewRect,
  148.                     listFontNumber,
  149.                     PARM.fontSize,
  150.                     PARM.logDisplayLines,
  151.                     TRUE
  152.                 );
  153.             FailNIL(DOC.logListHandle, kErrCreateTextWindow);
  154.             /*
  155.              * Force an update event so the window looks good when it starts.
  156.              * Otherwise, there's a long pause if the Audit record is full.
  157.              */
  158.             BeginUpdate(WINDOW_PTR);
  159.             TextFont(applFont);
  160.             TextSize(kApplFontSize);
  161.             TextFace(normal);
  162.             PenNormal();
  163.             UpdateControls(WINDOW_PTR, WINDOW_PTR->visRgn);
  164.             UpdateDocumentWindow(documentPtr);
  165.             DrawGrowIcon(WINDOW_PTR);
  166.             EndUpdate(theWindow);
  167.             /*
  168.              * Create a log file if requested. (Error is non-fatal).
  169.              */            
  170.             if (sfReply.good == FALSE)
  171.                 DOC.logFileRefNum = 0;
  172.             else {
  173.                 status = CreateOutputFile(
  174.                             'ttxt',
  175.                             sfReply.fName,
  176.                             sfReply.vRefNum,
  177.                             &DOC.logFileRefNum
  178.                         );
  179.                 if (status != noErr) {
  180.                     DOC.logFileRefNum = 0;
  181.                     ErrorAlert(status, kErrCreateOutputFile, FALSE);
  182.                 }
  183.                 else {
  184.                     DOC.logFileVRefNum = sfReply.vRefNum;
  185.                     pstrcpy(DOC.logFileName, sfReply.fName);
  186.                 }
  187.             }
  188.             DOC.auditPtr = GetAuditPtr(DOC.auditIdent);
  189.             if (DOC.auditPtr != NULL)
  190.                 message = "\pAudit Record was previously created";
  191.             else {
  192.                 DOC.auditPtr = InitAudit(
  193.                             DOC.auditIdent,
  194.                             PARM.auditRecords,
  195.                             DOC.enableAudit,
  196.                             FALSE
  197.                         );
  198.                 message = "\pAudit Record created";
  199.             }
  200.             GetCurrentProcess(&DOC.oldPSN);
  201.             WakeUpAudit(DOC.auditPtr, &DOC.oldPSN);
  202.             saveAuditEnable = EnableAudit(DOC.auditPtr, TRUE);
  203.             Audit(
  204.                 DOC.auditPtr,
  205.                 'APPL',
  206.                 AuditFormat3(
  207.                     kAuditFormatHex,
  208.                     kAuditFormatAddress,
  209.                     kAuditFormatString
  210.                 ),
  211.                 DOC.auditIdent,
  212.                 DOC.auditPtr,
  213.                 message
  214.             );
  215.             EnableAudit(DOC.auditPtr, saveAuditEnable);
  216. #if TESTING
  217.             AuditString(
  218.                 DOC.auditPtr,
  219.                 'Moof',
  220.                 "\p1234567890123456789012345678901234567890"
  221.             );
  222.             AuditStatusString(DOC.auditPtr, 'Moof', 1, "\pHello world");
  223.             AuditStatusLocation(DOC.auditPtr, 'Moof', 2);
  224.             TestAuditStatusLocationUsingAnExtremelyLongFunctionName();
  225.             TestPascalVoidFunction();
  226.             TestPascalShortFunction();
  227.             TestPascalFunctionWithParameters(NULL, NULL);
  228.             {
  229.                     long            i;
  230.                     unsigned long    foo;
  231.                     
  232.                     foo = 0x00010203;
  233.                     for (i = 0; i < (256 / 4); i++) {
  234.                         Audit(
  235.                             DOC.auditPtr,
  236.                             foo,
  237.                             AuditFormat2(kAuditFormatSigned, kAuditFormatHex),
  238.                             i,
  239.                             foo
  240.                         );
  241.                         foo += 0x04040404;
  242.                     }
  243.             }
  244. #endif                            
  245.         }
  246.         CATCH {
  247.             if (DOC.logListHandle != NULL)
  248.                 DisposeLog(DOC.logListHandle);
  249.             if (DOC.logFileRefNum != 0) {
  250.                 (void) FSClose(DOC.logFileRefNum);
  251.                 (void) FSDelete(DOC.logFileName, DOC.logFileVRefNum);
  252.             }
  253.             DisposePtr((Ptr) documentPtr);
  254.         }
  255.         ENDTRY;
  256. }
  257.  
  258. void
  259. TimeStamp(
  260.         register DocumentPtr            documentPtr
  261.     )
  262. {
  263.         Str255                            work;
  264.         TEHandle                        teHandle;
  265.         
  266.         teHandle = GetTEHandle(DOC.tagEditHandle);
  267.         GetIText((**teHandle).hText, work);
  268.         AuditString(DOC.auditPtr, '••••', work);
  269. }
  270.  
  271. void
  272. ProcessAuditDocument(
  273.         register DocumentPtr            documentPtr
  274.     )
  275. {
  276.         register short            i;
  277.         
  278.         for (i = 0; i < DOC.scanCount && ReadAudit(DOC.auditPtr, &ENTRY); i++)
  279.             ProcessAuditEntry(documentPtr);
  280. }
  281.  
  282. void
  283. ProcessAuditEntry(
  284.         register DocumentPtr            documentPtr
  285.     )
  286. {
  287.         Str255                            message;
  288.         Str255                            work;
  289.         short                            i;
  290.         
  291.         if (ENTRY.lostData > 0) {
  292.             DOC.totalMissedCount += ENTRY.lostData;
  293.             NumToString(ENTRY.lostData, message);
  294.             pstrcat(message, "\p log entries(");
  295.             NumToString(DOC.totalMissedCount, work);
  296.             pstrcat(message, work);
  297.             pstrcat(message, "\p total) missed...");
  298.             DisplayLogString(DOC.logListHandle, message);
  299.             DOC.logIndex += ENTRY.lostData;
  300.         }
  301.         DOC.logIndex += 1;
  302.         message[0] = 0;
  303.         NumToString(DOC.logIndex, work);
  304.         for (i = work[0]; i < 3; i++)
  305.             pstrcat(message, "\p ");
  306.         pstrcat(message, work);
  307.         pstrcat(message, "\p ");
  308.         FormatAuditEntryTimestamp(DOC.auditPtr, &ENTRY, work);
  309.         /*
  310.          * Since we know that the timestamp has a fixed-length format, we can chop
  311.          * out the date to gain some space in the text window. Note the format:
  312.          *        0        1         2
  313.          *        12345678901234567890123
  314.          *        1993.01.14 22:36:57.123
  315.          */
  316.         work[11] = work[0] - 11;
  317.         pstrcat(message, &work[11]);
  318.         pstrcat(message, "\p ");
  319.         FormatAuditEntryData(&ENTRY, work);
  320.         pstrcat(message, work);
  321.         DisplayLogString(DOC.logListHandle, message);
  322.         if (DOC.logFileRefNum != 0) {
  323.             TRY {
  324.                 WriteAuditOutputLine(message, DOC.logFileRefNum);
  325.             }
  326.             CATCH {
  327.                 ErrorAlert(STATUS, MESSAGE, FALSE);
  328.                 GetIndString(work, STRN_Messages, kErrWriteOutputFile);
  329.                 AuditStatusString(DOC.auditPtr, 'APPL', STATUS, work);
  330.                 CloseAuditOutputFile(
  331.                     STATUS,
  332.                     DOC.logFileRefNum,
  333.                     DOC.logFileVRefNum,
  334.                     DOC.logFileName
  335.                 );
  336.                 DOC.logFileRefNum = 0;
  337.                 NO_PROPAGATE;
  338.                 gUpdateMenusNeeded = TRUE;
  339.             }
  340.             ENDTRY;
  341.         }
  342. }
  343.  
  344. /*
  345.  * These are passed more-or-less intact to the log manager.
  346.  * Changing the EditMenu is not good programming practice.
  347.  */
  348. void
  349. DoWindowKeyDown(
  350.         register DocumentPtr            documentPtr
  351.     )
  352. {
  353.         if (DoTextEditEvent(DOC.tagEditHandle, &EVENT))
  354.             AdjustEditMenu(DOC.tagEditHandle);
  355. }
  356.  
  357. void
  358. DoWindowNullEvent(
  359.         register DocumentPtr            documentPtr
  360.     )
  361. {
  362.         DoTextEditEvent(DOC.tagEditHandle, &EVENT);
  363. }
  364.  
  365. void
  366. AdjustDocumentEditMenu(
  367.         register DocumentPtr            documentPtr
  368.     )
  369. {
  370.         AdjustEditMenu(DOC.tagEditHandle);
  371. }
  372. void
  373. DoDocumentEditMenu(
  374.         register DocumentPtr            documentPtr,
  375.         short                            menuItem
  376.     )
  377. {
  378.         ManageEditMenu(DOC.tagEditHandle, menuItem);
  379. }
  380.  
  381. void
  382. DoContentClick(
  383.         register DocumentPtr            documentPtr
  384.     )
  385. {
  386.         ControlHandle                    theControl;
  387.         short                            partCode;
  388.         Point                            mousePt;
  389.         
  390.         if (DoTextEditEvent(DOC.tagEditHandle, &EVENT))
  391.             AdjustEditMenu(DOC.tagEditHandle);
  392.         else if (DoClickInLog(DOC.logListHandle, &EVENT) == FALSE) {
  393.             mousePt = EVENT.where;
  394.             GlobalToLocal(&mousePt);
  395.             partCode = FindControl(mousePt, WINDOW_PTR, &theControl);
  396.             if (partCode != 0 && theControl == DOC.tagButton) {
  397.                 TextFont(applFont);
  398.                 TextSize(kApplFontSize);
  399.                 TextFace(normal);
  400.                 if (TrackControl(theControl, mousePt, NULL) == inButton)
  401.                     TimeStamp(documentPtr);
  402.             }
  403.         }
  404. }
  405.  
  406. void
  407. UpdateDocumentWindow(
  408.         register DocumentPtr            documentPtr
  409.     )
  410. {
  411.         Rect                            viewRect;
  412.         TEHandle                        teHandle;
  413.         
  414.         DrawGrowIcon(WINDOW_PTR);
  415.         UpdateLog(DOC.logListHandle);
  416.         GetTagViewRect(documentPtr, &viewRect);
  417.         FrameRect(&viewRect);
  418.         teHandle = GetTEHandle(DOC.tagEditHandle);
  419.         TEUpdate(&WINDOW_PTR->portRect, teHandle);
  420. }
  421.  
  422. void
  423. ActivateDocumentWindow(
  424.         register DocumentPtr            documentPtr,
  425.         Boolean                            isActivating
  426.     )
  427. {
  428.         TEHandle                        teHandle;
  429.  
  430.         ActivateLog(DOC.logListHandle, isActivating);
  431.         teHandle = GetTEHandle(DOC.tagEditHandle);
  432.         if (isActivating)
  433.             TEActivate(teHandle);
  434.         else {
  435.             TEDeactivate(teHandle);
  436.         }
  437. }
  438.  
  439. void
  440. DisposeDocumentWindow(
  441.         register DocumentPtr            documentPtr
  442.     )
  443. {
  444.         OSErr                        status;
  445.         short                        message;
  446.         
  447.         status = noErr;
  448.         if (DOC.tagEditHandle != NULL)
  449.             DisposeEditHandle(DOC.tagEditHandle);
  450.         if (DOC.auditPtr != NULL)
  451.             WakeUpAudit(DOC.auditPtr, &DOC.oldPSN);
  452.         if (DOC.logFileRefNum != 0) {
  453.             TRY {
  454.                 CloseAuditOutputFile(
  455.                     noErr,
  456.                     DOC.logFileRefNum,
  457.                     DOC.logFileVRefNum,
  458.                     DOC.logFileName
  459.                 );
  460.             }
  461.             CATCH {
  462.                 status = STATUS;
  463.                 message = MESSAGE;
  464.                 NO_PROPAGATE;
  465.             }
  466.             ENDTRY;
  467.         }
  468.         CloseWindow(WINDOW_PTR);
  469.         DisposePtr((Ptr) documentPtr);
  470.         if (--gOpenWindowCount <= 0)
  471.             gQuitNow = TRUE;
  472.         FailOSErr(status, message);
  473. }
  474.  
  475. void
  476. DecorateWindow(
  477.         register DocumentPtr            documentPtr
  478.     )
  479. {
  480.         Rect                            viewRect;
  481.         
  482.         SizeLog(
  483.             DOC.logListHandle,
  484.             width(WINDOW.portRect) - kScrollBarOffset,
  485.             height(WINDOW.portRect) - kScrollBarOffset - DOC.tagLine
  486.         );
  487.         GetTagViewRect(documentPtr, &viewRect);
  488.         RepositionEditItem(DOC.tagEditHandle, &viewRect);
  489. }
  490.  
  491. void
  492. DoDocumentSaveAs(
  493.         register DocumentPtr            documentPtr
  494.     )
  495. {
  496.         if (DOC.logFileRefNum != 0)
  497.             DoDocumentCloseFile(documentPtr);
  498.         TRY {
  499.             PromptAndCreateAuditOutputFile(
  500.                 "\pAudit Output File",
  501.                 "\pAudit Log",
  502.                 'ttxt',
  503.                 &DOC.logFileRefNum,
  504.                 &DOC.logFileVRefNum,
  505.                 DOC.logFileName
  506.             );
  507.         }
  508.         CATCH {
  509.             ErrorAlert(STATUS, MESSAGE, FALSE);
  510.             NO_PROPAGATE;
  511.         }
  512.         ENDTRY;
  513. }
  514.  
  515. void
  516. DoDocumentCloseFile(
  517.         register DocumentPtr            documentPtr
  518.     )
  519. {
  520.         TRY {
  521.             CloseAuditOutputFile(
  522.                 noErr,
  523.                 DOC.logFileRefNum,
  524.                 DOC.logFileVRefNum,
  525.                 DOC.logFileName
  526.             );
  527.         }
  528.         CATCH {
  529.             ErrorAlert(STATUS, MESSAGE, FALSE);
  530.             NO_PROPAGATE;
  531.         }
  532.         ENDTRY;
  533.         DOC.logFileRefNum = 0;
  534.         gUpdateMenusNeeded = TRUE;
  535. }
  536.  
  537. #if TESTING
  538. /*
  539.  * These were used to test the Audit library and are retained because I'm a kind
  540.  * of sentimental guy.
  541.  */
  542. #define AuditLocation(ident) (                            \
  543.         Audit(                                            \
  544.             ((DocumentPtr) FrontWindow())->auditPtr,    \
  545.             (ident),                                    \
  546.             AuditFormat1(kAuditFormatLocation)            \
  547.         )                                                \
  548.     )
  549.  
  550. void
  551. TestAuditStatusLocationUsingAnExtremelyLongFunctionName(void) {
  552.         AuditLocation('Moof');
  553. }
  554.  
  555. pascal void
  556. TestPascalVoidFunction(void)
  557. {
  558.         AuditLocation('Moof');
  559. }
  560.  
  561. pascal short
  562. TestPascalShortFunction(void)
  563. {
  564.         AuditLocation('Moof');
  565.         return (123);
  566. }
  567. pascal OSErr
  568. TestPascalFunctionWithParameters(
  569.         Ptr                        fooPtr,
  570.         Ptr                        barPtr
  571.     )
  572. {
  573.         AuditLocation('Moof');
  574.         return ((fooPtr == barPtr) ? noErr : paramErr);
  575. }
  576. #endif
  577.  
  578.